home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / POV-Ray 3.0.2 / src / MacSource / Printf2Window.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-10-07  |  70.5 KB  |  2,154 lines  |  [TEXT/CWIE]

  1. /*
  2. ==============================================================================
  3. Project:    POV-Ray
  4.  
  5. Version:    3
  6.  
  7. File Name:    Printf2Window.c
  8.  
  9. Description:
  10.     General-purpose printf-capturing routines that allow a console-like
  11.     output window for c programs that otherwise prefer to use printf/fprintf.
  12.     This code was "inspired heavily" from sources such as MacDTS'es TESample,
  13.     MacApp's Transcript window, and previous code of mine.  It is fairly well
  14.     self-contained, and works in MPW C 3.2 and Think C 5.0.
  15.  
  16.     This is the main source file, containing the private definitions and
  17.     code to implement all the needed external and internal support functions.
  18.  
  19. Related Files:
  20.     Stdio_p2w.h        - generic header for sources that would otherwise use <stdio.h>
  21.     Printf2Window.h    - Mac-specific header for p2w routines
  22.     Printf2Window.c    - the main source for the p2w routines
  23. ------------------------------------------------------------------------------
  24. Author:
  25.     Eduard [esp] Schwan
  26. ------------------------------------------------------------------------------
  27.     from Persistence of Vision(tm) Ray Tracer
  28.     Copyright 1996 Persistence of Vision Team
  29. ------------------------------------------------------------------------------
  30.     NOTICE: This source code file is provided so that users may experiment
  31.     with enhancements to POV-Ray and to port the software to platforms other 
  32.     than those supported by the POV-Ray Team.  There are strict rules under
  33.     which you are permitted to use this file.  The rules are in the file
  34.     named POVLEGAL.DOC which should be distributed with this file. If 
  35.     POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  36.     Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  37.     Forum.  The latest version of POV-Ray may be found there as well.
  38.  
  39.     This program is based on the popular DKB raytracer version 2.12.
  40.     DKBTrace was originally written by David K. Buck.
  41.     DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  42. ------------------------------------------------------------------------------
  43. Change History:
  44.     920318    [esp]    Created.
  45.     920325    [esp]    Added init/Terminate, major redesign of std c fns.
  46.     920327    [esp]    Robustized AddCString code that handles TERec-is-full delete logic
  47.     920329    [esp]    Added AdjustScrollBars call in AddCString to update scrollers as text is added
  48.     920330    [esp]    Updated file header with copyright & related files info
  49.     920401    [esp]    Added p2wSignature to window record for safety checking
  50.     920402    [esp]    Fixed cr/lf bug in bottleneck routine
  51.     920412    [esp]    Fixed potential integer overflow in comparison in AddCString routine
  52.     920412    [esp]    Added most function header comments, added windBounds support in Newp2wWindow, fixed scroller activate bug
  53.     920413    [esp]    Fixed misbehavin' scrollbars hilite upon activate/deactivate
  54.     920521    [esp]    Made the non-resource based code work.
  55.     920529    [esp]    Changed type defs to have trailing _t for ANSI consistency
  56.     920529    [esp]    Added p2w_SetTextFont function to allow easy fontsize switching
  57.     920603    [esp]    Initialized newly alloc'ed ctrls to VISIBLE
  58.     920816    [esp]    Added p2w_SelectAll routine
  59.     920901    [esp]    reduced kMaxTELength to 32000 so TeachText doesn't choke on >32000 sized files!
  60.     920905    [esp]    Fixed scrollbars so they're inactive on window creation.
  61.     920912    [esp]    Added windID parm to NewWindow call
  62.     921011    [esp]    Updated bottleneck to handle fopen() file I/O too (pass-through)
  63.     921128    [esp]    Fixed bug in p2w_fputs: the newline went to stdout, not stream!
  64.     931001    [esp]    version 2.0 finished (Released on 10/4/93)
  65.     931119    [djh]    2.0.1 conditionally compiles for PPC machines, keyword __powerc
  66.     940416    [PFS]    2.2.1 greatly reworked to clean up PPC support and provide CodeWarrior projects
  67.     940430    [esp]    Preliminary 3.0a1 work
  68.     950825    [esp]    Fixed to ignore various control chars (like backspace)
  69.     951226    [esp]    Fixed activate/deactivate aesthetic bugs, started updating toolbox names
  70. ==============================================================================
  71. */
  72.  
  73. #include "printf2window.h"    /* our defs AND stdio.h for sprintf, etc. */
  74. #include "screenUtils.h"    /* GetMaxGrowRect */
  75.  
  76. /* Standard C library headers */
  77. #include <stdarg.h>        // ANSI C variable length argument support
  78. #include <string.h>        // strlen
  79.  
  80. /* Macintosh-specific headers */
  81. #include <Types.h>
  82. #include <Controls.h>
  83. #include <Dialogs.h>
  84. #include <Files.h>
  85. #include <Memory.h>
  86. #include <OSUtils.h>
  87. #include <Resources.h>
  88. #include <Windows.h>
  89. #include <Scrap.h>
  90.  
  91. #if !defined(THINK_C)
  92. #include <strings.h>        /*p2cstr*/
  93. #endif // THINK_C
  94.  
  95.  
  96. #if defined(powerc) || defined (__powerc)
  97. // even Apple has fixed this... no longer needed
  98. // extern QDGlobals qd;
  99. #endif
  100.  
  101. // ==== Constant definitions
  102.  
  103. // Comment USE_P2W_RESOURCES out to create the controls from scratch..
  104. // Leave it in to create them from resources
  105.  
  106. // #define    USE_P2W_RESOURCES    true
  107.  
  108.  
  109. // Resource IDs of supporting p2w resources
  110.  
  111. #if defined(USE_P2W_RESOURCES)
  112. #define    kp2w_VScrollID        9601
  113. #define    kp2w_HScrollID        9602
  114. #endif // USE_P2W_RESOURCES
  115.  
  116.  
  117. // Magic p2w window record signature value
  118.  
  119. #define    kp2wWindowSignature    'p2w '
  120.  
  121.  
  122. // kTextMargin is the number of pixels we leave blank at the edge of the window.
  123.  
  124. #define kTextMargin                2
  125.  
  126.  
  127. // kControlInvisible is used to 'turn off' controls (i.e., cause the control not
  128. // to be redrawn as a result of some Control Manager call such as SetControlValue)
  129. // by being put into the contrlVis field of the record. kControlVisible is used
  130. // the same way to 'turn on' the control.
  131.  
  132. #define kControlInvisible        0
  133. #define kControlVisible            0xFF
  134.  
  135.  
  136. // kControlHiliteActive is used to activate controls (contrlHilite)
  137. // kControlHiliteInactive is used to deactivate controls (contrlHilite)
  138.  
  139. #define kControlHiliteActive        0
  140. #define kControlHiliteInactive        0xFF
  141.  
  142.  
  143. // kButtonScroll is how many pixels to scroll horizontally when the button part
  144. // of the horizontal scrollbar is pressed.
  145.  
  146. #define kButtonScroll            4
  147.  
  148. // kScrollbarAdjust and kScrollbarWidth are used in calculating
  149. // values for control positioning and sizing.
  150.  
  151. #define kScrollbarWidth            16
  152. #define kScrollbarAdjust        (kScrollbarWidth - 1)
  153.  
  154.  
  155. // kScrollTweek compensates for off-by-one requirements of the scrollbars
  156. // to have borders coincide with the growbox.
  157.  
  158. #define kScrollTweek            2
  159.  
  160.  
  161. // kMaxTELength is an arbitrary number used to limit the length of text in the TERec
  162. // so that various errors won't occur from too many characters in the text.  When the
  163. // string to be added exceeds kMaxTELength, then strlen+kTEDeleteChunkSize
  164. // characters will be deleted from the beginning of the TERec.  This lets the TE
  165. // buffer stay pretty full while characters "fall off the top" of the buffer, and
  166. // insures that the performance delay of deleting from the front of the buffer
  167. // only happens every once in awhile, instead of for every single additional
  168. // string added.  kTEDeleteChunkSize should probably be between 1k and 20k..
  169.  
  170. #define    kMaxTELength            32000    // 32000 is pretty close to 32767, OK SimpleText?
  171. #define    kTEDeleteChunkSize        6000    // should be between 1000 and 20000
  172.  
  173.  
  174. // kMinDocSize is the smallest horiz/vert size of a grown window.
  175.  
  176. #define    kMinDocSize                100
  177.  
  178.  
  179. // kMaxStdIOBuffSize is the largest supported size of a single formatted
  180. // stdio C string.  Note that internally, a relocatable buffer of this size
  181. // will be allocated.
  182.  
  183. #define    kMaxStdIOBuffSize        1024
  184.  
  185.  
  186. // internal macro definitions
  187.  
  188. // Define some structure accessing macros for efficiency.
  189. #define GET_HIWORD(aLong)    (((aLong)>>16)&0x0FFFFL)
  190. #define GET_LOWORD(aLong)    ((aLong)&0x0FFFFL)
  191. #define GET_TOPLEFT_POINT(aRect)    (*(Point*)&(aRect).top)
  192. #define GET_BOTRIGHT_POINT(aRect)    (*(Point*)&(aRect).bottom)
  193. #define GET_RECT_WIDTH(aRect)        ((aRect).right - (aRect).left)
  194. #define GET_RECT_HEIGHT(aRect)        ((aRect).bottom - (aRect).top)
  195. #define IS_P2W_WINDOW(p2wPtr) (((p2w_WindowPtr_t)p2wPtr)->p2wSignature == kp2wWindowSignature)
  196.  
  197. /*
  198. ----------------------------------
  199. prototypes for internal routines
  200. ----------------------------------
  201. */
  202.  
  203. static void p2wi_GetTERect(const p2w_WindowPtr_t thep2wWindow, Rect *teRect);
  204. static void p2wi_AdjustTE(const p2w_WindowPtr_t thep2wWindow);
  205. static void p2wi_AdjustViewRect(TEHandle p2wTE);
  206. static void p2wi_CommonAdjustScroller(const Boolean isVert, const p2w_WindowPtr_t thep2wWindow,
  207.                              ControlHandle control, TEHandle theTEHandle/*, const Boolean canRedraw*/);
  208. static void p2wi_AdjustScrollValues(const p2w_WindowPtr_t thep2wWindow/*,  const Boolean doRedraw*/);
  209. static void p2wi_AdjustScrollSizes(const p2w_WindowPtr_t thep2wWindow);
  210. static void p2wi_AdjustScrollbars(const p2w_WindowPtr_t thep2wWindow, const Boolean doResize);
  211. static void p2wi_ResizeWindow(const p2w_WindowPtr_t thep2wWindow);
  212. static void p2wi_GetLocalUpdateRegion(const p2w_WindowPtr_t thep2wWindow, RgnHandle localRgn);
  213. static void p2wi_CommonScrollAction(ControlHandle control, short *amount);
  214. pascal void p2wi_VScrollActionProc(ControlHandle control, short part);
  215. pascal void p2wi_HScrollActionProc(ControlHandle control, short part);
  216. static int p2wi_StdCOut_BottleNeck(FILE *stream);
  217. static int p2wi_vfprintf(FILE *stream, const char *format, va_list va_args);
  218.  
  219.  
  220.  
  221. /*
  222. ----------------------------------
  223. global variable definitions
  224. ----------------------------------
  225. */
  226.  
  227. static Handle            p2w_Stdio_OutBuf_Hdl = NULL;
  228. static p2w_WindowPtr_t    local_p2wWindow = NULL;
  229.  
  230. static ControlActionUPP p2wi_VScrollActionUPP = NULL;
  231. static ControlActionUPP p2wi_HScrollActionUPP = NULL;
  232.  
  233.  
  234. /*---------------------------------------------------------------------*/
  235. /*==== Main interface routines ====*/
  236.  
  237.  
  238. /*
  239. ******************************************************************************
  240. Name:
  241.     p2w_Init
  242. ------------------------------------------------------------------------------
  243. Purpose:
  244.     Primary (one-time) initialization of the p2w routines
  245. ------------------------------------------------------------------------------
  246. Description:
  247.     pre-allocates internal storage & initializes variables
  248. ------------------------------------------------------------------------------
  249. Parameters:
  250.     void
  251. ------------------------------------------------------------------------------
  252. When Used:
  253.     Called once, when the application starts up
  254. ******************************************************************************
  255. */
  256. OSErr p2w_Init(void)
  257. {
  258.     OSErr    anError = noErr;
  259.  
  260.     // allocate an output character stream buffer to use
  261.     p2w_Stdio_OutBuf_Hdl = NewHandle(kMaxStdIOBuffSize + sizeof(short));
  262.     anError = MemError();
  263.     local_p2wWindow = NULL;
  264.  
  265.     p2wi_VScrollActionUPP = NewControlActionProc(p2wi_VScrollActionProc);
  266.     p2wi_HScrollActionUPP = NewControlActionProc(p2wi_HScrollActionProc);
  267.  
  268.     return anError;
  269. } // p2w_Init
  270.  
  271.  
  272.  
  273. /*
  274. ******************************************************************************
  275. Name:
  276.     p2w_Terminate
  277. ------------------------------------------------------------------------------
  278. Purpose:
  279.     Primary (one-time) destruction of the p2w routines
  280. ------------------------------------------------------------------------------
  281. Description:
  282.     de-allocates internal storage & invalidates variables
  283. ------------------------------------------------------------------------------
  284. Parameters:
  285.     void
  286. ------------------------------------------------------------------------------
  287. When Used:
  288.     Called once, when the application is shutting down
  289. ******************************************************************************
  290. */
  291. OSErr p2w_Terminate(void)
  292. {
  293.     OSErr    anError = noErr;
  294.  
  295.     if (p2w_Stdio_OutBuf_Hdl)
  296.     {
  297.         DisposeHandle(p2w_Stdio_OutBuf_Hdl);
  298.         anError = MemError();
  299.     }
  300.     p2w_Stdio_OutBuf_Hdl = NULL;
  301.     local_p2wWindow = NULL;
  302.  
  303.     return anError;
  304. } // p2w_Terminate
  305.  
  306.  
  307.  
  308. /*
  309. ******************************************************************************
  310. Name:
  311.     p2w_NewWindow
  312. ------------------------------------------------------------------------------
  313. Purpose:
  314.     Creates a new p2w window structure for use by other p2w routines.
  315. ------------------------------------------------------------------------------
  316. Description:
  317.     Creates a p2w window (either from resources or from parameters),
  318.     initializes it, and shows it if asked.
  319. ------------------------------------------------------------------------------
  320. Parameters:
  321.     windID            if 0, create window from scratch, if > 0, use as ID for GetNewWindow
  322.     windBoundsPtr    Where to place the new window on the screen.
  323.                     If NULL, the resource bounds will be used.
  324.     windTitle        The Pascal title string to use for the new window.
  325.                     If NULL, resource title will be used.
  326.     windIsVisible    TRUE will show window after creation, FALSE will leave hidden.
  327.     windFont        Text Font to use for new window.
  328.     windFontSize    Text Font Size tose for new window.
  329.     anError            Returns any error code, or zero (noErr) if all went OK.
  330. ------------------------------------------------------------------------------
  331. When Used:
  332.     Called when a new p2w window needs to be allocated.  It may or may not
  333.     be shown at this time.  It will be opened in the back.  This call mainly 
  334.     creates the window structures.
  335. ******************************************************************************
  336. */
  337. p2w_WindowPtr_t p2w_NewWindow(    const    short        windID,
  338.                                 const    Rect        *windBoundsPtr,
  339.                                 const    Str255        windTitle,
  340.                                 const    Boolean        windIsVisible,
  341.                                 const    int            windFont,
  342.                                 const    short        windFontSize,
  343.                                         OSErr        *anError)
  344. {
  345.     WindowPtr        aWindow;
  346.     Rect            destRect, viewRect, screenRect;
  347.     p2w_WindowPtr_t    p2wWPtr = NULL;
  348.     GrafPtr            savedPort;
  349.  
  350.     GetPort(&savedPort);    // I'll be back..
  351.  
  352.     /* how big is the screen */
  353.     screenRect = qd.screenBits.bounds;
  354.  
  355.     /* allocate space for our extended p2window record */
  356.     p2wWPtr = (p2w_WindowPtr_t)NewPtr(sizeof(p2w_WindowRecord_t));
  357.     *anError = MemError();
  358.     if (!*anError)
  359.     {
  360.         // initialize the p2w record
  361.  
  362.         p2wWPtr->p2wSignature        = kp2wWindowSignature; // bless this special window record
  363.         p2wWPtr->p2wOpenedOK        = false; // until actually opened later
  364.         p2wWPtr->p2wTEHandle        = NULL;
  365.         p2wWPtr->p2wVScroller        = NULL;
  366.         p2wWPtr->p2wHScroller        = NULL;
  367.         p2wWPtr->p2wClickHandler    = NULL;
  368.         p2wWPtr->p2wMaxDocWidth        = GET_RECT_WIDTH(screenRect) - kScrollbarWidth - 2*kTextMargin - 10;
  369.         p2wWPtr->p2wAlwaysScrollToBottom    = true;
  370.  
  371.         /* now create the Window */
  372.         if (windID > 0)
  373.         { // get from resource
  374.             aWindow = GetNewWindow(windID, p2wWPtr, (WindowPtr)NULL);
  375.             *anError = ResError();
  376.         }
  377.         else
  378.         { // Create from scratch, also moves/sizes appropriately
  379.             aWindow = NewWindow(p2wWPtr, windBoundsPtr, windTitle, windIsVisible, documentProc,
  380.                                 (WindowPtr)NULL, false/*hasGoAway*/, 0/*refcon*/);
  381.             *anError = MemError();
  382.         }
  383.     }
  384.  
  385.     /* Move the window to user-specified position? */
  386.     /* Do this only if getting from resources - already done (above) otherwise */
  387.     if (windID > 0)
  388.     {
  389.         if ((!*anError) && (windBoundsPtr != NULL))
  390.         {
  391.             MoveWindow(aWindow, (*windBoundsPtr).left, (*windBoundsPtr).top, false);
  392.             SizeWindow(aWindow, GET_RECT_WIDTH(*windBoundsPtr), GET_RECT_HEIGHT(*windBoundsPtr), false);
  393.         }
  394.     }
  395.  
  396.     if (!*anError)
  397.     {
  398.         // now its OK to call CloseWindow later..
  399.         p2wWPtr->p2wOpenedOK = true;
  400.  
  401.         SetPort(aWindow);
  402.  
  403.         /* Set its title to what the user passed in, if non-null */
  404.         /* Do this only if getting from resources - already done (above) otherwise */
  405.         if (windID > 0)
  406.             if (windTitle)                            // not a NULL pointer?
  407.                 if (*windTitle)                        // not an empty string?
  408.                     SetWTitle(aWindow, windTitle);    // then do it!
  409.  
  410.         /* set up the font in the port */
  411.         p2w_SetTextFont(p2wWPtr, windFont, windFontSize);
  412.  
  413.         /* set up the EditText buffer & area */
  414.         p2wi_GetTERect(p2wWPtr, &viewRect);
  415.         destRect = viewRect;
  416.         destRect.right = destRect.left + p2wWPtr->p2wMaxDocWidth;
  417.         p2wWPtr->p2wTEHandle = TENew(&destRect, &viewRect);
  418.         *anError = MemError();
  419.     }
  420.  
  421.     if (!*anError)
  422.     {
  423.         p2wi_AdjustViewRect(p2wWPtr->p2wTEHandle);
  424.     }
  425.  
  426.     /* Create vertical scrollbar */
  427.     if (!*anError)
  428.     {
  429. #if defined(USE_P2W_RESOURCES)
  430.         p2wWPtr->p2wVScroller = GetNewControl(kp2w_VScrollID, aWindow);
  431.         *anError = ResError();
  432. #else
  433.         p2wWPtr->p2wVScroller = NewControl(aWindow, &(*aWindow).portRect, "\pp2w_Vert", false, 0, 0, 1, scrollBarProc, 0);
  434.         *anError = MemError();
  435. #endif // USE_P2W_RESOURCES
  436.     }
  437.  
  438.     /* Create horizontal scrollbar */
  439.     if (!*anError)
  440.     {
  441. #if defined(USE_P2W_RESOURCES)
  442.         p2wWPtr->p2wHScroller = GetNewControl(kp2w_HScrollID, aWindow);
  443.         *anError = ResError();
  444. #else
  445.         p2wWPtr->p2wHScroller = NewControl(aWindow, &(*aWindow).portRect, "\pp2w_Horz", false, 0, 0, 1, scrollBarProc, 0);
  446.         *anError = MemError();
  447. #endif // USE_P2W_RESOURCES
  448.     }
  449.  
  450.     // adjust & draw the controls, draw the window
  451.     if (!*anError)
  452.     {
  453.         // turn on auto-scrolling and outline hilighting
  454.         TEDeactivate(p2wWPtr->p2wTEHandle);
  455. /*
  456. turn on autoscrolling if/when we add a clickloop proc...
  457.         (void)TEFeatureFlag(teFAutoScr,        teBitSet, p2wWPtr->p2wTEHandle);
  458. */
  459.         (void)TEFeatureFlag(teFOutlineHilite, teBitSet, p2wWPtr->p2wTEHandle);
  460.         p2wi_AdjustScrollbars(p2wWPtr, true/*kResize*/);
  461.         // Our window comes up in back, so turn OFF visibility of scrollbar initially
  462.         HideControl(p2wWPtr->p2wVScroller);
  463.         HideControl(p2wWPtr->p2wHScroller);
  464.         if (windIsVisible)
  465.             ShowWindow(aWindow);
  466.     }
  467.  
  468.     // Return to port after storm
  469.     SetPort(savedPort);    // I'm back..
  470.  
  471.     // close & dispose if any errors happened!
  472.     if (*anError)
  473.     {
  474.         p2w_DisposeWindow(p2wWPtr);
  475.         // if errors happened, don't give user any pointers
  476.         p2wWPtr = NULL;
  477.     }
  478.  
  479.     // remember this for the StdIO routines later..
  480.     local_p2wWindow = p2wWPtr;
  481.  
  482.     return (p2wWPtr);
  483.  
  484. } // p2w_NewWindow
  485.  
  486.  
  487.  
  488. /*
  489. ******************************************************************************
  490. Name:
  491.     p2w_DisposeWindow
  492. ------------------------------------------------------------------------------
  493. Purpose:
  494.     Deletes an existing p2w window structure and its related TE danglies.
  495. ------------------------------------------------------------------------------
  496. Description:
  497.     Disposes of the TE record, closes the window/grafport, and disposes
  498.     of the window/grafport itself.
  499. ------------------------------------------------------------------------------
  500. Parameters:
  501.     the_p2wPtr        The p2w window to dispose.
  502. ------------------------------------------------------------------------------
  503. When Used:
  504.     Called when a p2w window is no longer needed.
  505. ******************************************************************************
  506. */
  507. void p2w_DisposeWindow(p2w_WindowPtr_t the_p2wPtr)
  508. {
  509.     // Is the window pointer not null?
  510.     if (the_p2wPtr)
  511.         // is this really one of our p2w windows?
  512.         // (We don't want to dispose extra stuff if it's really
  513.         // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
  514.         if (IS_P2W_WINDOW(the_p2wPtr))
  515.         {
  516.             // Dispose Window/GrafPort danglies if opened ok
  517.             if (the_p2wPtr->p2wOpenedOK)
  518.                 CloseWindow((WindowPtr)the_p2wPtr);
  519.             // Dispose of our TE Record
  520.             if (the_p2wPtr->p2wTEHandle)
  521.                 TEDispose(the_p2wPtr->p2wTEHandle);
  522.             // set fields back to nil, to help catch anyone touching them after dispose!
  523.             the_p2wPtr->p2wOpenedOK        = false;
  524.             the_p2wPtr->p2wTEHandle        = NULL;
  525.             the_p2wPtr->p2wVScroller    = NULL;
  526.             the_p2wPtr->p2wHScroller    = NULL;
  527.             the_p2wPtr->p2wClickHandler    = NULL;
  528.             // Dispose our version of window record itself now
  529.             DisposePtr((Ptr)the_p2wPtr);
  530.             local_p2wWindow = NULL;
  531.         }
  532. } // p2w_DisposeWindow
  533.  
  534.  
  535. /*
  536. ******************************************************************************
  537. Name:
  538.     p2w_SetTextFont
  539. ------------------------------------------------------------------------------
  540. Purpose:
  541.     Changes the Font Type and Size in the p2w window.
  542. ------------------------------------------------------------------------------
  543. Description:
  544. ------------------------------------------------------------------------------
  545. Parameters:
  546.     the_p2wPtr        The p2w window to update.
  547.     newFontType        The Font type to change to (monaco, courier, times, etc.)
  548.     newFontSize        The Font type to change to (9,10,12,etc.)
  549. ------------------------------------------------------------------------------
  550. When Used:
  551.     Called when text is to be added to the p2w window.
  552. ******************************************************************************
  553. */
  554. void p2w_SetTextFont
  555.                     (        p2w_WindowPtr_t        the_p2wPtr,
  556.                             short                newFontType,
  557.                             short                newFontSize)
  558. {
  559.     GrafPtr            savedPort;
  560.  
  561.     GetPort(&savedPort);    // I'll be back..
  562.  
  563.     // is this really one of our p2w windows?
  564.     // (We don't want to fiddle with extra stuff if it's really
  565.     // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
  566.     if (IS_P2W_WINDOW(the_p2wPtr))
  567.     {
  568.         // Tell our grafport that we have a new font
  569.         SetPort((GrafPtr)the_p2wPtr);
  570.         TextFont(newFontType);
  571.         TextSize(newFontSize);
  572.  
  573.         // Tell our TextEdit record that we have a new font..
  574.         if (the_p2wPtr->p2wTEHandle != NULL)
  575.         {    // TE Record is valid
  576.             (**the_p2wPtr->p2wTEHandle).txFont = newFontType;
  577.             (**the_p2wPtr->p2wTEHandle).txSize = newFontSize;
  578.             // let the TE adjust to this new font!
  579.             TECalText(the_p2wPtr->p2wTEHandle);
  580.             TEUpdate(&the_p2wPtr->p2wWindowRec.port.portRect,the_p2wPtr->p2wTEHandle);
  581.         }
  582.     }
  583.     // Return to port after storm
  584.     SetPort(savedPort);    // I'm back..
  585.  
  586. } // p2w_SetTextFont
  587.  
  588. /*
  589. ******************************************************************************
  590. Name:
  591.     p2w_AlwaysScrollToBottom
  592. ------------------------------------------------------------------------------
  593. Purpose:
  594.     Changes behavior of p2w to stay put, or always scroll to bottom
  595. ------------------------------------------------------------------------------
  596. Description:
  597. ------------------------------------------------------------------------------
  598. Parameters:
  599.     the_p2wPtr        The p2w window to update.
  600. ------------------------------------------------------------------------------
  601. When Used:
  602.     Called when you want to set whether it always scrolls to bottom
  603. ******************************************************************************
  604. */
  605. void p2w_AlwaysScrollToBottom(p2w_WindowPtr_t the_p2wPtr, Boolean alwaysScroll)
  606. {
  607.     if (the_p2wPtr)        // if window ptr is valid
  608.         // is this really one of our p2w windows?
  609.         // (We don't want to fiddle with extra stuff if it's really
  610.         // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
  611.         if (IS_P2W_WINDOW(the_p2wPtr) && the_p2wPtr->p2wVScroller)
  612.             {
  613.             the_p2wPtr->p2wAlwaysScrollToBottom    = alwaysScroll;
  614.             }
  615. }
  616.  
  617. /*
  618. ******************************************************************************
  619. Name:
  620.     p2w_AlwaysScrollToBottomState
  621. ------------------------------------------------------------------------------
  622. Purpose:
  623.     Changes behavior of p2w to stay put, or always scroll to bottom
  624. ------------------------------------------------------------------------------
  625. Description:
  626. ------------------------------------------------------------------------------
  627. Parameters:
  628.     the_p2wPtr        The p2w window to update.
  629. ------------------------------------------------------------------------------
  630. When Used:
  631.     Called when you want to find out whether it always scrolls to bottom
  632. ******************************************************************************
  633. */
  634. Boolean p2w_AlwaysScrollToBottomState(p2w_WindowPtr_t the_p2wPtr)
  635. {
  636.     if (the_p2wPtr)        // if window ptr is valid
  637.         // is this really one of our p2w windows?
  638.         // (We don't want to fiddle with extra stuff if it's really
  639.         // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
  640.         if (IS_P2W_WINDOW(the_p2wPtr) && the_p2wPtr->p2wVScroller)
  641.             {
  642.             return the_p2wPtr->p2wAlwaysScrollToBottom;
  643.             }
  644.     return false;
  645. }
  646.  
  647. /*
  648. ******************************************************************************
  649. Name:
  650.     p2w_ScrollHome
  651. ------------------------------------------------------------------------------
  652. Purpose:
  653.     Forcese the p2w window to scroll to the top and redraw.
  654. ------------------------------------------------------------------------------
  655. Description:
  656. ------------------------------------------------------------------------------
  657. Parameters:
  658.     the_p2wPtr        The p2w window to update.
  659. ------------------------------------------------------------------------------
  660. When Used:
  661.     Called when you want to force the window to display the top of the text.
  662. ******************************************************************************
  663. */
  664. void p2w_ScrollHome(p2w_WindowPtr_t the_p2wPtr)
  665. {
  666.     short    controlMin,controlVal;
  667.     int        scrollAmt;
  668.  
  669.     if (the_p2wPtr)        // if window ptr is valid
  670.         // is this really one of our p2w windows?
  671.         // (We don't want to fiddle with extra stuff if it's really
  672.         // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
  673.         if (IS_P2W_WINDOW(the_p2wPtr) && the_p2wPtr->p2wVScroller)
  674.             {
  675.             // get current scroll settings
  676.             controlMin = GetControlMinimum(the_p2wPtr->p2wVScroller);
  677.             controlVal = GetControlValue(the_p2wPtr->p2wVScroller);
  678.             
  679.             // calculate how far to scroll to get back to the top
  680.             scrollAmt = controlVal-controlMin;
  681.             if (scrollAmt>0)
  682.                 {
  683.                 // set scrollbar to top/min
  684.                 SetControlValue(the_p2wPtr->p2wVScroller, controlMin);
  685.                 // scroll the TE record to match the scrollbars
  686.                 p2wi_AdjustTE(the_p2wPtr);
  687.                 // re-draw the scrollbars, forcing them to go to the top
  688.                 p2wi_AdjustScrollbars(the_p2wPtr, true); // force redraw
  689.                 }
  690.             }
  691. }
  692.  
  693. /*
  694. ******************************************************************************
  695. Name:
  696.     p2w_ScrollEnd
  697. ------------------------------------------------------------------------------
  698. Purpose:
  699.     Forcese the p2w window to scroll to the bottom and redraw.
  700. ------------------------------------------------------------------------------
  701. Description:
  702. ------------------------------------------------------------------------------
  703. Parameters:
  704.     the_p2wPtr        The p2w window to update.
  705. ------------------------------------------------------------------------------
  706. When Used:
  707.     Called when you want to force the window to display the end of the text.
  708. ******************************************************************************
  709. */
  710. void p2w_ScrollEnd(p2w_WindowPtr_t        the_p2wPtr)
  711. {
  712.     short    controlMax,controlVal;
  713.     int        scrollAmt;
  714.  
  715.     if (the_p2wPtr)        // if window ptr is valid
  716.         // is this really one of our p2w windows?
  717.         // (We don't want to fiddle with extra stuff if it's really
  718.         // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
  719.         if (IS_P2W_WINDOW(the_p2wPtr) && the_p2wPtr->p2wVScroller)
  720.             {
  721.             // get current scroll settings
  722.             controlMax = GetControlMaximum(the_p2wPtr->p2wVScroller);
  723.             controlVal = GetControlValue(the_p2wPtr->p2wVScroller);
  724.             
  725.             // calculate how far to scroll to get back to the top
  726.             scrollAmt = controlMax-controlVal;
  727.             if (scrollAmt>0)
  728.                 {
  729.                 // set scrollbar to top/min
  730.                 SetControlValue(the_p2wPtr->p2wVScroller, controlMax);
  731.                 // scroll the TE record to match the scrollbars
  732.                 p2wi_AdjustTE(the_p2wPtr);
  733.                 // re-draw the scrollbars, forcing them to go to the top
  734.                 p2wi_AdjustScrollbars(the_p2wPtr, true); // force redraw
  735.                 }
  736.             }
  737. }
  738.  
  739.  
  740. /*
  741. ******************************************************************************
  742. Name:
  743.     p2w_ScrollPageUp
  744. ------------------------------------------------------------------------------
  745. Purpose:
  746.     Forces the p2w window to scroll a page.
  747. ------------------------------------------------------------------------------
  748. Description:
  749. ------------------------------------------------------------------------------
  750. Parameters:
  751.     the_p2wPtr        The p2w window to scroll.
  752. ------------------------------------------------------------------------------
  753. When Used:
  754. ******************************************************************************
  755. */
  756. void p2w_ScrollPageUp(p2w_WindowPtr_t        the_p2wPtr)
  757. {
  758.     if (the_p2wPtr)        // if window ptr is valid
  759.         // is this really one of our p2w windows?
  760.         // (We don't want to fiddle with extra stuff if it's really
  761.         // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
  762.         if (IS_P2W_WINDOW(the_p2wPtr) && the_p2wPtr->p2wVScroller)
  763.             {
  764.             // Pretend to click page-up
  765.             p2wi_VScrollActionProc(the_p2wPtr->p2wVScroller, kControlPageUpPart);
  766.             }
  767. }
  768.  
  769.  
  770. /*
  771. ******************************************************************************
  772. Name:
  773.     p2w_ScrollPageDown
  774. ------------------------------------------------------------------------------
  775. Purpose:
  776.     Forces the p2w window to scroll a page.
  777. ------------------------------------------------------------------------------
  778. Description:
  779. ------------------------------------------------------------------------------
  780. Parameters:
  781.     the_p2wPtr        The p2w window to scroll.
  782. ------------------------------------------------------------------------------
  783. When Used:
  784. ******************************************************************************
  785. */
  786. void p2w_ScrollPageDown(p2w_WindowPtr_t        the_p2wPtr)
  787. {
  788.     if (the_p2wPtr)        // if window ptr is valid
  789.         // is this really one of our p2w windows?
  790.         // (We don't want to fiddle with extra stuff if it's really
  791.         // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
  792.         if (IS_P2W_WINDOW(the_p2wPtr) && the_p2wPtr->p2wVScroller)
  793.             {
  794.             // Pretend to click page-up
  795.             p2wi_VScrollActionProc(the_p2wPtr->p2wVScroller, kControlPageDownPart);
  796.             }
  797. }
  798.  
  799.  
  800. /*
  801. ******************************************************************************
  802. Name:
  803.     p2w_ScrollLineUp
  804. ------------------------------------------------------------------------------
  805. Purpose:
  806.     Forces the p2w window to scroll a line.
  807. ------------------------------------------------------------------------------
  808. Description:
  809. ------------------------------------------------------------------------------
  810. Parameters:
  811.     the_p2wPtr        The p2w window to scroll.
  812. ------------------------------------------------------------------------------
  813. When Used:
  814. ******************************************************************************
  815. */
  816. void p2w_ScrollLineUp(p2w_WindowPtr_t        the_p2wPtr)
  817. {
  818.     if (the_p2wPtr)        // if window ptr is valid
  819.         // is this really one of our p2w windows?
  820.         // (We don't want to fiddle with extra stuff if it's really
  821.         // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
  822.         if (IS_P2W_WINDOW(the_p2wPtr) && the_p2wPtr->p2wVScroller)
  823.             {
  824.             // Pretend to click page-up
  825.             p2wi_VScrollActionProc(the_p2wPtr->p2wVScroller, kControlUpButtonPart);
  826.             }
  827. }
  828.  
  829.  
  830. /*
  831. ******************************************************************************
  832. Name:
  833.     p2w_ScrollLineDown
  834. ------------------------------------------------------------------------------
  835. Purpose:
  836.     Forces the p2w window to scroll a line.
  837. ------------------------------------------------------------------------------
  838. Description:
  839. ------------------------------------------------------------------------------
  840. Parameters:
  841.     the_p2wPtr        The p2w window to scroll.
  842. ------------------------------------------------------------------------------
  843. When Used:
  844. ******************************************************************************
  845. */
  846. void p2w_ScrollLineDown(p2w_WindowPtr_t        the_p2wPtr)
  847. {
  848.     if (the_p2wPtr)        // if window ptr is valid
  849.         // is this really one of our p2w windows?
  850.         // (We don't want to fiddle with extra stuff if it's really
  851.         // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
  852.         if (IS_P2W_WINDOW(the_p2wPtr) && the_p2wPtr->p2wVScroller)
  853.             {
  854.             // Pretend to click page-up
  855.             p2wi_VScrollActionProc(the_p2wPtr->p2wVScroller, kControlDownButtonPart);
  856.             }
  857. }
  858.  
  859.  
  860. /*
  861. ******************************************************************************
  862. Name:
  863.     p2w_ScrollLeft
  864. ------------------------------------------------------------------------------
  865. Purpose:
  866.     Forces the p2w window to scroll left.
  867. ------------------------------------------------------------------------------
  868. Description:
  869. ------------------------------------------------------------------------------
  870. Parameters:
  871.     the_p2wPtr        The p2w window to scroll.
  872. ------------------------------------------------------------------------------
  873. When Used:
  874. ******************************************************************************
  875. */
  876. void p2w_ScrollLeft(p2w_WindowPtr_t        the_p2wPtr)
  877. {
  878.     if (the_p2wPtr)        // if window ptr is valid
  879.         // is this really one of our p2w windows?
  880.         // (We don't want to fiddle with extra stuff if it's really
  881.         // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
  882.         if (IS_P2W_WINDOW(the_p2wPtr) && the_p2wPtr->p2wHScroller)
  883.             {
  884.             // Pretend to click left arrow
  885.             p2wi_HScrollActionProc(the_p2wPtr->p2wHScroller, kControlUpButtonPart);
  886.             }
  887. }
  888.  
  889.  
  890. /*
  891. ******************************************************************************
  892. Name:
  893.     p2w_ScrollRight
  894. ------------------------------------------------------------------------------
  895. Purpose:
  896.     Forces the p2w window to scroll right.
  897. ------------------------------------------------------------------------------
  898. Description:
  899. ------------------------------------------------------------------------------
  900. Parameters:
  901.     the_p2wPtr        The p2w window to scroll.
  902. ------------------------------------------------------------------------------
  903. When Used:
  904. ******************************************************************************
  905. */
  906. void p2w_ScrollRight(p2w_WindowPtr_t        the_p2wPtr)
  907. {
  908.     if (the_p2wPtr)        // if window ptr is valid
  909.         // is this really one of our p2w windows?
  910.         // (We don't want to fiddle with extra stuff if it's really
  911.         // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
  912.         if (IS_P2W_WINDOW(the_p2wPtr) && the_p2wPtr->p2wHScroller)
  913.             {
  914.             // Pretend to click page-up
  915.             p2wi_HScrollActionProc(the_p2wPtr->p2wHScroller, kControlDownButtonPart);
  916.             }
  917. }
  918.  
  919.  
  920. /*
  921. ******************************************************************************
  922. Name:
  923.     p2w_AddCString
  924. ------------------------------------------------------------------------------
  925. Purpose:
  926.     Adds the text in the C-style string passed to the p2w window.
  927. ------------------------------------------------------------------------------
  928. Description:
  929. ------------------------------------------------------------------------------
  930. Parameters:
  931.     the_p2wPtr        The p2w window to add to.
  932.     theCStrPtr        The string of text to add.
  933.     p2w_AddCString    function returns zero if ok, or an error #.
  934. ------------------------------------------------------------------------------
  935. When Used:
  936.     Called when text is to be added to the p2w window.
  937. ******************************************************************************
  938. */
  939. OSErr p2w_AddCString(p2w_WindowPtr_t the_p2wPtr, const char * theCStrPtr, short size)
  940. {
  941.     OSErr    anError = noErr;
  942.     long    oldStart, oldEnd;
  943.  
  944.     if (the_p2wPtr && theCStrPtr)        // if window and string ptrs are valid
  945.         // is this really one of our p2w windows?
  946.         // (We don't want to fiddle with extra stuff if it's really
  947.         // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
  948.         if (IS_P2W_WINDOW(the_p2wPtr))
  949.             if (the_p2wPtr->p2wTEHandle)
  950.             {    // TE Record is valid
  951.                 if (size > 0)    // if string is not empty, add it
  952.                 {
  953.                     // If TE is too full, need to delete some at beginning before adding
  954.                     // (this looks weird, but it is the Mathematically Correct way to
  955.                     // compare numbers close to the edge of 32767-land.. note that
  956.                     // teLength+size could overflow, so we subtract instead.)
  957.                     if ((**(the_p2wPtr->p2wTEHandle)).teLength > (kMaxTELength - size))
  958.                     {
  959.                         // Delete some text at beginning of TE
  960.                         TESetSelect(0, size+kTEDeleteChunkSize, the_p2wPtr->p2wTEHandle);
  961.                         TEDelete(the_p2wPtr->p2wTEHandle);
  962.                     }
  963.                     // Save selection start/end so we don't wipe out user's selection
  964.                     oldStart = (**the_p2wPtr->p2wTEHandle).selStart;
  965.                     oldEnd = (**the_p2wPtr->p2wTEHandle).selEnd;
  966.                     // go to very end of TE (-1 is really +65535 in TE Worlds!)
  967.                     TESetSelect(-1, -1, the_p2wPtr->p2wTEHandle);
  968.                     // stick it in there
  969.                     TEInsert(theCStrPtr, size, the_p2wPtr->p2wTEHandle);
  970.                     // restore user's selection before we redraw!
  971.                     (**the_p2wPtr->p2wTEHandle).selStart = oldStart;
  972.                     (**the_p2wPtr->p2wTEHandle).selEnd = oldEnd;
  973.                     // re-draw the scrollbars, since they may have changed
  974.                     p2wi_AdjustScrollbars(the_p2wPtr, true); // force redraw?
  975.                     /* now scroll the TE record to match the scrollbars */
  976.                     p2wi_AdjustTE(the_p2wPtr);
  977.                 }    // size > 0
  978.             }    // TE Record is valid
  979.     return(anError);
  980. } // p2w_AddCString
  981.  
  982.  
  983. /*
  984. ******************************************************************************
  985. Name:
  986.     p2w_DrawWindow
  987. ------------------------------------------------------------------------------
  988. Purpose:
  989.     Draw the contents of an application window.
  990. ------------------------------------------------------------------------------
  991. Description:
  992.     
  993. ------------------------------------------------------------------------------
  994. Parameters:
  995.     
  996. ------------------------------------------------------------------------------
  997. When Used:
  998.     
  999. ******************************************************************************
  1000. */
  1001. void p2w_DrawWindow(const p2w_WindowPtr_t the_p2wPtr)
  1002. {
  1003.     // is this really one of our p2w windows?
  1004.     // (We don't want to dispose extra stuff if it's really
  1005.     // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
  1006.     if (IS_P2W_WINDOW(the_p2wPtr))
  1007.     {
  1008.         // move in for the kill
  1009.         SetPort((WindowPtr)the_p2wPtr);
  1010.         // kill off old bits
  1011.         EraseRect(&((WindowPtr)the_p2wPtr)->portRect);
  1012.         // show them our text
  1013.         TEUpdate(&((WindowPtr)the_p2wPtr)->portRect, the_p2wPtr->p2wTEHandle);
  1014.         // redraw controls
  1015.         DrawControls((WindowPtr)the_p2wPtr);
  1016.         DrawGrowIcon((WindowPtr)the_p2wPtr);
  1017.     }
  1018. } // p2w_DrawWindow
  1019.  
  1020.  
  1021.  
  1022. /*
  1023. ******************************************************************************
  1024. Name:
  1025.     p2w_DoUpdate
  1026. ------------------------------------------------------------------------------
  1027. Purpose:
  1028.     Update (redraw) the contents of an application window.
  1029. ------------------------------------------------------------------------------
  1030. Description:
  1031.     
  1032. ------------------------------------------------------------------------------
  1033. Parameters:
  1034.     
  1035. ------------------------------------------------------------------------------
  1036. When Used:
  1037.     
  1038. ******************************************************************************
  1039. */
  1040. void p2w_DoUpdate(const p2w_WindowPtr_t thep2wWindow)
  1041. {
  1042.     // move in for the kill
  1043.     SetPort((WindowPtr)thep2wWindow);
  1044.     BeginUpdate((WindowPtr)thep2wWindow);                /* this sets up the visRgn */
  1045.     if (!EmptyRgn(((WindowPtr)thep2wWindow)->visRgn))    /* draw if updating needs to be done */
  1046.         p2w_DrawWindow(thep2wWindow);
  1047.     EndUpdate((WindowPtr)thep2wWindow);
  1048. } // p2w_DoUpdate
  1049.  
  1050.  
  1051. /*
  1052. ******************************************************************************
  1053. Name:
  1054.     p2w_DoActivate
  1055. ------------------------------------------------------------------------------
  1056. Purpose:
  1057.     This is called when a window is activated or deactivated.
  1058.     It calls TextEdit to handle the selection.
  1059. ------------------------------------------------------------------------------
  1060. Description:
  1061.     
  1062. ------------------------------------------------------------------------------
  1063. Parameters:
  1064.     
  1065. ------------------------------------------------------------------------------
  1066. When Used:
  1067.     
  1068. ******************************************************************************
  1069. */
  1070. void p2w_DoActivate(const p2w_WindowPtr_t thep2wWindow, Boolean becomingActive)
  1071. {
  1072.  
  1073.     // is this really one of our p2w windows?
  1074.     // (We don't want to dispose extra stuff if it's really
  1075.     // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
  1076.     if (IS_P2W_WINDOW(thep2wWindow))
  1077.     {
  1078.         /* move in for the kill */
  1079.         SetPort((WindowPtr)thep2wWindow);
  1080.  
  1081.         if (becomingActive)
  1082.         {
  1083. //        RgnHandle    tempRgn, clipRgn;
  1084. //        Rect        growRect;
  1085.             // Since we don’t want TEActivate to draw a selection
  1086.             // in an area where we’re going to erase and redraw,
  1087.             // we’ll clip out the update region before calling it.
  1088. /* don't do this...?
  1089.             tempRgn = NewRgn();
  1090.             clipRgn = NewRgn();
  1091.             if (tempRgn && clipRgn)
  1092.             {
  1093.                 p2wi_GetLocalUpdateRegion(thep2wWindow, tempRgn);    // get localized update region
  1094.                 GetClip(clipRgn);
  1095.                 DiffRgn(clipRgn, tempRgn, tempRgn);        // subtract updateRgn from clipRgn
  1096.                 SetClip(tempRgn);
  1097.                 TEActivate(thep2wWindow->p2wTEHandle);
  1098.                 SetClip(clipRgn);                        // restore the full-blown clipRgn
  1099.                 DisposeRgn(tempRgn);
  1100.                 DisposeRgn(clipRgn);
  1101.             }
  1102. */TEActivate(thep2wWindow->p2wTEHandle);
  1103.  
  1104.             DrawGrowIcon((WindowPtr)thep2wWindow);
  1105.  
  1106.             // the controls must be redrawn on activation
  1107.             ShowControl(thep2wWindow->p2wVScroller);
  1108.             ShowControl(thep2wWindow->p2wHScroller);
  1109.         }
  1110.         else
  1111.         {    /* De-Activating.. */
  1112.             /* the growbox should be changed immediately here */
  1113.             DrawGrowIcon((WindowPtr)thep2wWindow);
  1114.     
  1115.             TEDeactivate(thep2wWindow->p2wTEHandle);
  1116.     
  1117.             /* the controls must be hidden on deactivation */
  1118.             HideControl(thep2wWindow->p2wVScroller);
  1119.             HideControl(thep2wWindow->p2wHScroller);
  1120.  
  1121.         }
  1122.     }
  1123. } // p2w_DoActivate
  1124.  
  1125.  
  1126. /*
  1127. ******************************************************************************
  1128. Name:
  1129.     p2w_DoGrow
  1130. ------------------------------------------------------------------------------
  1131. Purpose:
  1132.     Called when a mouseDown occurs in the grow box of an active
  1133.     window. In order to eliminate any 'flicker', we want to
  1134.     invalidate only what is necessary. Since p2w_ResizeWindow
  1135.     invalidates the whole portRect, we save the old TE
  1136.     viewRect, intersect it with the new TE viewRect, and remove
  1137.     the result from the update region. However, we must make
  1138.     sure that any old update region that might have been around
  1139.     gets put back. 
  1140. ------------------------------------------------------------------------------
  1141. Description:
  1142.     
  1143. ------------------------------------------------------------------------------
  1144. Parameters:
  1145.     
  1146. ------------------------------------------------------------------------------
  1147. When Used:
  1148.     
  1149. ******************************************************************************
  1150. */
  1151. void p2w_DoGrow(const p2w_WindowPtr_t thep2wWindow, EventRecord *theEvent)
  1152. {
  1153.     long        growResult;
  1154.     Rect        tempRect;
  1155. //    RgnHandle    tempRgn;
  1156.     
  1157.     // is this really one of our p2w windows?
  1158.     // (We don't want to dispose extra stuff if it's really
  1159.     // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
  1160.     if (IS_P2W_WINDOW(thep2wWindow))
  1161.     {
  1162.         // move in for the kill
  1163.         SetPort((WindowPtr)thep2wWindow);
  1164.     
  1165.         /* set up limiting values */
  1166.         GetMaxGrowRect((WindowPtr)thep2wWindow, &tempRect);    // ScreenUtils.h
  1167.         tempRect.left = kMinDocSize;
  1168.         tempRect.top = kMinDocSize;
  1169.     
  1170.         growResult = GrowWindow((WindowPtr)thep2wWindow, theEvent->where, &tempRect);
  1171.         /* see if it really changed size */
  1172.         if (growResult != 0)
  1173.         {
  1174. //            tempRect = (**thep2wWindow->p2wTEHandle).viewRect;    /* save old text box */
  1175. //            tempRgn = NewRgn();
  1176. //            p2wi_GetLocalUpdateRegion(thep2wWindow, tempRgn);        /* get localized update region */
  1177.             SizeWindow((WindowPtr)thep2wWindow, GET_LOWORD(growResult), GET_HIWORD(growResult), true);
  1178.             p2wi_ResizeWindow(thep2wWindow);
  1179.     
  1180.             /* calculate & validate the region that hasn’t changed, so it won’t get redrawn */
  1181. //            SectRect(&tempRect, &(**thep2wWindow->p2wTEHandle).viewRect, &tempRect);
  1182. //            ValidRect(&tempRect);                            /* take it out of update */
  1183. //            InvalRgn(tempRgn);                                /* put back any prior update */
  1184. //            DisposeRgn(tempRgn);
  1185.         }
  1186.     }
  1187. } // p2w_DoGrow
  1188.  
  1189.  
  1190. /*
  1191. ******************************************************************************
  1192. Name:
  1193.     p2w_DoZoom
  1194. ------------------------------------------------------------------------------
  1195. Purpose:
  1196.     Called when a mouseClick occurs in the zoom box of an active
  1197.     window. Everything has to get re-drawn here, so we don't mind
  1198.     that p2w_ResizeWindow invalidates the whole portRect. 
  1199. ------------------------------------------------------------------------------
  1200. Description:
  1201.     
  1202. ------------------------------------------------------------------------------
  1203. Parameters:
  1204.     
  1205. ------------------------------------------------------------------------------
  1206. When Used:
  1207.     
  1208. ******************************************************************************
  1209. */
  1210. void p2w_DoZoom(const p2w_WindowPtr_t thep2wWindow, short thePart)
  1211. {
  1212.     // is this really one of our p2w windows?
  1213.     // (We don't want to dispose extra stuff if it's really
  1214.     // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
  1215.     if (IS_P2W_WINDOW(thep2wWindow))
  1216.     {
  1217.         // move in for the kill
  1218.         SetPort((WindowPtr)thep2wWindow);
  1219.         EraseRect(&((WindowPtr)thep2wWindow)->portRect);
  1220.         ZoomWindow((WindowPtr)thep2wWindow, thePart, (WindowPtr)thep2wWindow==FrontWindow());
  1221.         p2wi_ResizeWindow(thep2wWindow);
  1222.     }
  1223. } // p2w_DoZoom
  1224.  
  1225.  
  1226. /*
  1227. ******************************************************************************
  1228. Name:
  1229.     p2w_SelectAll
  1230. ------------------------------------------------------------------------------
  1231. Purpose:
  1232.     This will select the entire contents of a window.
  1233. ------------------------------------------------------------------------------
  1234. Description:
  1235.     
  1236. ------------------------------------------------------------------------------
  1237. Parameters:
  1238.     
  1239. ------------------------------------------------------------------------------
  1240. When Used:
  1241.     
  1242. ******************************************************************************
  1243. */
  1244. void p2w_SelectAll(const p2w_WindowPtr_t thep2wWindow)
  1245. {
  1246.     // is this really one of our p2w windows?
  1247.     // (We don't want to dispose extra stuff if it's really
  1248.     // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
  1249.     if (IS_P2W_WINDOW(thep2wWindow))
  1250.     {
  1251.         TESetSelect(0, -1, thep2wWindow->p2wTEHandle);
  1252.     }
  1253. } // p2w_SelectAll
  1254.  
  1255. /*
  1256. ******************************************************************************
  1257. Name:
  1258.     p2w_DoContentClick
  1259. ------------------------------------------------------------------------------
  1260. Purpose:
  1261.     This is called when a mouseDown occurs in the content of a window.
  1262. ------------------------------------------------------------------------------
  1263. Description:
  1264.     
  1265. ------------------------------------------------------------------------------
  1266. Parameters:
  1267.     
  1268. ------------------------------------------------------------------------------
  1269. When Used:
  1270.     
  1271. ******************************************************************************
  1272. */
  1273. void p2w_DoContentClick(const p2w_WindowPtr_t thep2wWindow, EventRecord *theEvent)
  1274. {
  1275.     Point        mouse;
  1276.     ControlHandle control;
  1277.     short        part, value;
  1278.     Boolean        shiftDown;
  1279.     Rect        teRect;
  1280.  
  1281.     // is this really one of our p2w windows?
  1282.     // (We don't want to dispose extra stuff if it's really
  1283.     // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
  1284.     if (IS_P2W_WINDOW(thep2wWindow))
  1285.     {
  1286.         SetPort((WindowPtr)thep2wWindow);
  1287.     
  1288.         /* get the click position */
  1289.         mouse = theEvent->where;
  1290.         GlobalToLocal(&mouse);
  1291.     
  1292.         /* see if we are in the viewRect. if so, we won’t check the controls */
  1293.         p2wi_GetTERect(thep2wWindow, &teRect);
  1294.         if (PtInRect(mouse, &teRect))
  1295.         {
  1296.             /* see if we need to extend the selection */
  1297.             shiftDown = (theEvent->modifiers & shiftKey) != 0;    /* extend if Shift is down */
  1298.             TEClick(mouse, shiftDown, thep2wWindow->p2wTEHandle);
  1299.         }
  1300.         else
  1301.         {
  1302.             part = FindControl(mouse, (WindowPtr)thep2wWindow, &control);
  1303.             switch (part)
  1304.             {
  1305.                 case 0:        /* do nothing.. */
  1306.                     break;
  1307.                 case kControlIndicatorPart:
  1308.                     value = GetControlValue(control);
  1309.                     part = TrackControl(control, mouse, nil);
  1310.                     if (part != 0)
  1311.                     {
  1312.                         value -= GetControlValue(control);
  1313.                         /* value now has CHANGE in value; if value changed, scroll */
  1314.                         if (value != 0)
  1315.                             if (control == thep2wWindow->p2wVScroller)
  1316.                                 TEScroll(0, value * (*thep2wWindow->p2wTEHandle)->lineHeight, thep2wWindow->p2wTEHandle);
  1317.                             else
  1318.                                 TEScroll(value, 0, thep2wWindow->p2wTEHandle);
  1319.                     }
  1320.                     break;
  1321.                 default:    /* they clicked in an arrow, so track & scroll */
  1322.                     if (control == thep2wWindow->p2wVScroller)
  1323.                     {
  1324.                         value = TrackControl(control, mouse, p2wi_VScrollActionUPP);
  1325.                     }
  1326.                     else
  1327.                     if (control == thep2wWindow->p2wHScroller)
  1328.                     {
  1329.                         value = TrackControl(control, mouse, p2wi_HScrollActionUPP);
  1330.                     }
  1331.                     break;
  1332.             }
  1333.         }
  1334.     }
  1335. } // p2w_DoContentClick
  1336.  
  1337.  
  1338. /*
  1339. ******************************************************************************
  1340. Name:
  1341.     p2w_DoKeyDown
  1342. ------------------------------------------------------------------------------
  1343. Purpose:
  1344.     Handle special keys, scroll window up/down.
  1345. ------------------------------------------------------------------------------
  1346. Description:
  1347. ------------------------------------------------------------------------------
  1348. Parameters:
  1349.     the_p2wPtr        The p2w window to scroll.
  1350. ------------------------------------------------------------------------------
  1351. When Used:
  1352. ******************************************************************************
  1353. */
  1354. void p2w_DoKeyDown(const p2w_WindowPtr_t        the_p2wPtr, short    theKeyCode)
  1355. {
  1356.     if (the_p2wPtr)        // if window ptr is valid
  1357.         // is this really one of our p2w windows?
  1358.         // (We don't want to fiddle with extra stuff if it's really
  1359.         // a normal [sheep] WindowPtr passed in as a [wolf] p2w_WindowPtr_t!)
  1360.         if (IS_P2W_WINDOW(the_p2wPtr))
  1361.             {
  1362.             switch (theKeyCode)
  1363.                 {
  1364.                 case 0x73:    // HOME
  1365.                     p2w_ScrollHome(the_p2wPtr);
  1366.                     break;
  1367.  
  1368.                 case 0x77:    // END
  1369.                     p2w_ScrollEnd(the_p2wPtr);
  1370.                     break;
  1371.  
  1372.                 case 0x74:    // page-up
  1373.                     p2w_ScrollPageUp(the_p2wPtr);
  1374.                     break;
  1375.  
  1376.                 case 0x79:    // page-down
  1377.                     p2w_ScrollPageDown(the_p2wPtr);
  1378.                     break;
  1379.  
  1380.                 case 0x7b:    // left-arrow
  1381.                 case 0x3b:
  1382.                     p2w_ScrollLeft(the_p2wPtr);
  1383.                     break;
  1384.  
  1385.                 case 0x7c:    // right-arrow
  1386.                 case 0x3c:
  1387.                     p2w_ScrollRight(the_p2wPtr);
  1388.                     break;
  1389.  
  1390.                 case 0x7e:    // up-arrow
  1391.                 case 0x3e:
  1392.                     p2w_ScrollLineUp(the_p2wPtr);
  1393.                     break;
  1394.  
  1395.                 case 0x7d:    // down-arrow
  1396.                 case 0x3d:
  1397.                     p2w_ScrollLineDown(the_p2wPtr);
  1398.                     break;
  1399.                 }
  1400.             }
  1401. }
  1402.  
  1403.  
  1404.  
  1405. /*---------------------------------------------------------------------*/
  1406. /*==== Private internal p2w routines ====*/
  1407.     
  1408. /*
  1409. ******************************************************************************
  1410. Name:
  1411.     p2wi_GetTERect
  1412. ------------------------------------------------------------------------------
  1413. Purpose:
  1414.     Return a rectangle that is inset from the portRect by the
  1415.     size of the scrollbars, plus a bit.
  1416. ------------------------------------------------------------------------------
  1417. Description:
  1418.     
  1419. ------------------------------------------------------------------------------
  1420. Parameters:
  1421.     
  1422. ------------------------------------------------------------------------------
  1423. When Used:
  1424.     
  1425. ******************************************************************************
  1426. */
  1427. static void p2wi_GetTERect(const p2w_WindowPtr_t thep2wWindow, Rect *teRect)
  1428. {
  1429.     *teRect = ((WindowPtr)thep2wWindow)->portRect;
  1430.     InsetRect(teRect, kTextMargin, kTextMargin);    /* adjust for margin */
  1431.     teRect->bottom = teRect->bottom - kScrollbarAdjust;        /* and for the scrollbars */
  1432.     teRect->right  = teRect->right  - kScrollbarAdjust;
  1433. } // p2wi_GetTERect
  1434.  
  1435.  
  1436. /*
  1437. ******************************************************************************
  1438. Name:
  1439.     p2wi_AdjustTE
  1440. ------------------------------------------------------------------------------
  1441. Purpose:
  1442.     Scroll the TERec around to match up to the potentially updated scrollbar
  1443.     values. This is really useful when the window has been resized such that
  1444.     the scrollbars became inactive but the TERec was already scrolled.
  1445. ------------------------------------------------------------------------------
  1446. Description:
  1447.     
  1448. ------------------------------------------------------------------------------
  1449. Parameters:
  1450.     
  1451. ------------------------------------------------------------------------------
  1452. When Used:
  1453.     
  1454. ******************************************************************************
  1455. */
  1456. static void p2wi_AdjustTE(const p2w_WindowPtr_t thep2wWindow)
  1457. {
  1458.     short        hVal,vVal;
  1459.     TEPtr        te;
  1460.     
  1461.     vVal = GetControlValue(thep2wWindow->p2wVScroller);
  1462.     hVal = GetControlValue(thep2wWindow->p2wHScroller);
  1463.     te = *thep2wWindow->p2wTEHandle;
  1464.     TEScroll((te->viewRect.left - te->destRect.left) - hVal,
  1465.              (te->viewRect.top  - te->destRect.top)  - (vVal * te->lineHeight),
  1466.             thep2wWindow->p2wTEHandle);
  1467. } // p2wi_AdjustTE
  1468.  
  1469.  
  1470. /*
  1471. ******************************************************************************
  1472. Name:
  1473.     p2wi_AdjustViewRect
  1474. ------------------------------------------------------------------------------
  1475. Purpose:
  1476.     Update our TE view rect so it's the greatest multiple of
  1477.     the lineHeight that still fits in the old viewRect.
  1478. ------------------------------------------------------------------------------
  1479. Description:
  1480.     
  1481. ------------------------------------------------------------------------------
  1482. Parameters:
  1483.     
  1484. ------------------------------------------------------------------------------
  1485. When Used:
  1486.     
  1487. ******************************************************************************
  1488. */
  1489. static void p2wi_AdjustViewRect(TEHandle p2wTE)
  1490. {
  1491.     TEPtr        te;
  1492.     
  1493.     te = *p2wTE;
  1494.     te->viewRect.bottom = (((te->viewRect.bottom - te->viewRect.top) / te->lineHeight)
  1495.                             * te->lineHeight) + te->viewRect.top;
  1496. } // p2wi_AdjustViewRect
  1497.  
  1498.  
  1499. /*
  1500. ******************************************************************************
  1501. Name:
  1502.     p2wi_CommonAdjustScroller
  1503. ------------------------------------------------------------------------------
  1504. Purpose:
  1505.     Calculate the new control maximum value and current value,
  1506.     for the horizontal or vertical scrollbar. The vertical max
  1507.     is calculated by comparing the number of lines to the
  1508.     vertical size of the viewRect. The horizontal max is
  1509.     calculated by comparing the maximum document width to the
  1510.     width of the viewRect. The current values are set by
  1511.     comparing the offset between the view and destination
  1512.     rects. If necessary and we canRedraw, have the control be
  1513.     re-drawn by calling ShowControl. 
  1514. ------------------------------------------------------------------------------
  1515. Description:
  1516.     
  1517. ------------------------------------------------------------------------------
  1518. Parameters:
  1519.     
  1520. ------------------------------------------------------------------------------
  1521. When Used:
  1522.     Called by p2wi_AdjustScrollValues, twice.
  1523. ******************************************************************************
  1524. */
  1525. static void p2wi_CommonAdjustScroller(const Boolean isVert, const p2w_WindowPtr_t thep2wWindow,
  1526.                                     ControlHandle control, TEHandle theTEHandle/*, const Boolean canRedraw*/)
  1527. {
  1528.     short        value, lines, theMax;
  1529.     short        oldValue, oldMax;
  1530.     
  1531.     // calculate new max and current values for this scrollbar
  1532.     oldValue = GetControlValue(control);
  1533.     oldMax   = GetControlMaximum(control);
  1534.     if (isVert)
  1535.     {
  1536.         lines = (**theTEHandle).nLines;
  1537.         /* since nLines isn’t right if the last character is a return, check for that case */
  1538.         if ( *(*(**theTEHandle).hText + (**theTEHandle).teLength - 1) == '\n')
  1539.             lines += 1;
  1540.         theMax = lines
  1541.             -    (
  1542.                 ((**theTEHandle).viewRect.bottom - (**theTEHandle).viewRect.top)
  1543.                 / (**theTEHandle).lineHeight
  1544.                 );
  1545.     }
  1546.     else // horiz
  1547.         theMax = thep2wWindow->p2wMaxDocWidth
  1548.             -    (
  1549.                 (**theTEHandle).viewRect.right - (**theTEHandle).viewRect.left
  1550.                 );
  1551.     
  1552.     if (theMax < 0) // insure positive
  1553.         theMax = 0;
  1554.     SetControlMaximum(control, theMax);
  1555.     
  1556.     if (isVert)
  1557.     {
  1558.         // always scroll to end?
  1559.         if (thep2wWindow->p2wAlwaysScrollToBottom)
  1560.             value = theMax;
  1561.         else
  1562.             value = ((**theTEHandle).viewRect.top - (**theTEHandle).destRect.top)
  1563.                     / (**theTEHandle).lineHeight;
  1564.     }
  1565.     else // horiz
  1566.         value = (**theTEHandle).viewRect.left - (**theTEHandle).destRect.left;
  1567.     
  1568.     if ( value < 0 )
  1569.         value = 0;
  1570.     else
  1571.         if (value >  theMax)
  1572.             value = theMax;
  1573.     
  1574.     SetControlValue(control, value);
  1575.  
  1576.     /* now redraw the control if it needs to be and can be */
  1577. /*
  1578.     if (canRedraw || (max != oldMax) || (value != oldValue))
  1579.     {
  1580.         ShowControl(control);
  1581.     }
  1582. */
  1583. } // p2wi_CommonAdjustScroller
  1584.  
  1585.  
  1586. /*
  1587. ******************************************************************************
  1588. Name:
  1589.     p2wi_AdjustScrollValues
  1590. ------------------------------------------------------------------------------
  1591. Purpose:
  1592.     Simply call the common adjust routine for both the vertical
  1593.     and horizontal scrollbars.
  1594. ------------------------------------------------------------------------------
  1595. Description:
  1596.     
  1597. ------------------------------------------------------------------------------
  1598. Parameters:
  1599.     
  1600. ------------------------------------------------------------------------------
  1601. When Used:
  1602.     
  1603. ******************************************************************************
  1604. */
  1605. static void p2wi_AdjustScrollValues(const p2w_WindowPtr_t thep2wWindow)
  1606. {
  1607.     // vertical
  1608.     p2wi_CommonAdjustScroller(true, thep2wWindow, thep2wWindow->p2wVScroller, thep2wWindow->p2wTEHandle);
  1609.     // horizontal
  1610.     p2wi_CommonAdjustScroller(false, thep2wWindow, thep2wWindow->p2wHScroller, thep2wWindow->p2wTEHandle);
  1611. } // p2wi_AdjustScrollValues
  1612.  
  1613.  
  1614.  
  1615. /*
  1616. ******************************************************************************
  1617. Name:
  1618.     p2wi_AdjustScrollSizes
  1619. ------------------------------------------------------------------------------
  1620. Purpose:
  1621.     Re-calculate the position and size of the viewRect and the
  1622.     scrollbars. The constant kScrollTweek compensates for the
  1623.     "off-by-one" requirements of the scrollbars that need their
  1624.     borders coinciding with the growbox. 
  1625. ------------------------------------------------------------------------------
  1626. Description:
  1627.     
  1628. ------------------------------------------------------------------------------
  1629. Parameters:
  1630.     
  1631. ------------------------------------------------------------------------------
  1632. When Used:
  1633.     
  1634. ******************************************************************************
  1635. */
  1636. static void p2wi_AdjustScrollSizes(const p2w_WindowPtr_t thep2wWindow)
  1637. {
  1638.     Rect        teRect;
  1639.  
  1640.     p2wi_GetTERect(thep2wWindow, &teRect);    // start with TERect..
  1641.     (*thep2wWindow->p2wTEHandle)->viewRect = teRect;
  1642.     p2wi_AdjustViewRect(thep2wWindow->p2wTEHandle);    /* snap to nearest line */
  1643.  
  1644.     /* move vertical scrollbar to nearest line */
  1645.     MoveControl(thep2wWindow->p2wVScroller,
  1646.                 ((WindowPtr)thep2wWindow)->portRect.right - kScrollbarAdjust,
  1647.                 -1);
  1648.     SizeControl(thep2wWindow->p2wVScroller,
  1649.                 kScrollbarWidth,
  1650.                 (((WindowPtr)thep2wWindow)->portRect.bottom
  1651.                     - ((WindowPtr)thep2wWindow)->portRect.top)
  1652.                     - (kScrollbarAdjust - kScrollTweek));
  1653.  
  1654.     /* move horizontal scrollbar to nearest line  */
  1655.     MoveControl(thep2wWindow->p2wHScroller,
  1656.                 -1,
  1657.                 ((WindowPtr)thep2wWindow)->portRect.bottom - kScrollbarAdjust);
  1658.     SizeControl(thep2wWindow->p2wHScroller,
  1659.                 (((WindowPtr)thep2wWindow)->portRect.right
  1660.                     - ((WindowPtr)thep2wWindow)->portRect.left)
  1661.                     - (kScrollbarAdjust - kScrollTweek),
  1662.                 kScrollbarWidth);
  1663. } // p2wi_AdjustScrollSizes
  1664.  
  1665.  
  1666. /*
  1667. ******************************************************************************
  1668. Name:
  1669.     p2wi_AdjustScrollbars
  1670. ------------------------------------------------------------------------------
  1671. Purpose:
  1672.     Recalculate the scrollbar pos/values, and redraw if need be.
  1673. ------------------------------------------------------------------------------
  1674. Description:
  1675.     Turn off the controls by jamming a zero into their contrlVis fields
  1676.     (HideControl erases them and we don't want that). If the controls
  1677.     are to be resized as well, call the procedure to do that, then call
  1678.     the procedure to adjust the maximum and current values. Finally,
  1679.     re-enable the controls by jamming a $FF in their contrlVis fields.  
  1680. ------------------------------------------------------------------------------
  1681. Parameters:
  1682.     
  1683. ------------------------------------------------------------------------------
  1684. When Used:
  1685.     
  1686. ******************************************************************************
  1687. */
  1688. static void p2wi_AdjustScrollbars(const p2w_WindowPtr_t thep2wWindow, const Boolean doResize)
  1689. {
  1690.     short    oldHvis, oldVvis;
  1691.  
  1692.     /* remember original visibility settings */
  1693.     oldVvis = (**thep2wWindow->p2wVScroller).contrlVis;
  1694.     oldHvis = (**thep2wWindow->p2wHScroller).contrlVis;
  1695.  
  1696.     /* First, turn visibility of scrollbars off to eliminate unwanted redrawing */
  1697.     (**thep2wWindow->p2wVScroller).contrlVis = kControlInvisible;    /* turn them off */
  1698.     (**thep2wWindow->p2wHScroller).contrlVis = kControlInvisible;
  1699.  
  1700.     /* move & size as needed */
  1701.     if (doResize)
  1702.         p2wi_AdjustScrollSizes(thep2wWindow);
  1703.  
  1704.     /* adjust constrols' max and current values */
  1705.     p2wi_AdjustScrollValues(thep2wWindow);
  1706.  
  1707.     /* Now, restore visibility in case we never had to ShowControl during adjustment */
  1708.     (**thep2wWindow->p2wVScroller).contrlVis = oldVvis;    /* restore them */
  1709.     (**thep2wWindow->p2wHScroller).contrlVis = oldHvis;
  1710.  
  1711. // don't do this?
  1712.     ShowControl(thep2wWindow->p2wVScroller);
  1713.     ShowControl(thep2wWindow->p2wHScroller);
  1714.  
  1715. } // p2wi_AdjustScrollbars
  1716.  
  1717.  
  1718. /*
  1719. ******************************************************************************
  1720. Name:
  1721.     p2wi_ResizeWindow
  1722. ------------------------------------------------------------------------------
  1723. Purpose:
  1724.     Called when the window has been resized to fix up the controls and content.
  1725. ------------------------------------------------------------------------------
  1726. Description:
  1727.     
  1728. ------------------------------------------------------------------------------
  1729. Parameters:
  1730.     
  1731. ------------------------------------------------------------------------------
  1732. When Used:
  1733.     
  1734. ******************************************************************************
  1735. */
  1736. static void p2wi_ResizeWindow(const p2w_WindowPtr_t thep2wWindow)
  1737. {
  1738.     p2wi_AdjustScrollbars(thep2wWindow, true);
  1739.     /* now scroll the TE record to match the scrollbars */
  1740.     p2wi_AdjustTE(thep2wWindow);
  1741.     InvalRect(&((WindowPtr)thep2wWindow)->portRect);
  1742. } // p2wi_ResizeWindow
  1743.  
  1744.  
  1745.  
  1746. /*
  1747. ******************************************************************************
  1748. Name:
  1749.     p2wi_GetLocalUpdateRegion
  1750. ------------------------------------------------------------------------------
  1751. Purpose:
  1752.     Returns the update region in local coordinates
  1753. ------------------------------------------------------------------------------
  1754. Description:
  1755.     
  1756. ------------------------------------------------------------------------------
  1757. Parameters:
  1758.     
  1759. ------------------------------------------------------------------------------
  1760. When Used:
  1761.     
  1762. ******************************************************************************
  1763. */
  1764. static void p2wi_GetLocalUpdateRegion(const p2w_WindowPtr_t thep2wWindow, RgnHandle localRgn)
  1765. {
  1766.     CopyRgn(((WindowPeek)thep2wWindow)->updateRgn, localRgn);    /* save old update region */
  1767.     OffsetRgn(localRgn, ((WindowPtr)thep2wWindow)->portBits.bounds.left,
  1768.                         ((WindowPtr)thep2wWindow)->portBits.bounds.top);
  1769. } // p2wi_GetLocalUpdateRegion
  1770.  
  1771.  
  1772.  
  1773. /*
  1774. ******************************************************************************
  1775. Name:
  1776.     p2wi_CommonScrollAction
  1777. ------------------------------------------------------------------------------
  1778. Purpose:
  1779.     Common algorithm for pinning the value of a control. It
  1780.     returns the actual amount the value of the control changed.
  1781.     Note the pinning is done for the sake of returning the
  1782.     amount the control value changed.
  1783. ------------------------------------------------------------------------------
  1784. Description:
  1785.     
  1786. ------------------------------------------------------------------------------
  1787. Parameters:
  1788.     
  1789. ------------------------------------------------------------------------------
  1790. When Used:
  1791.     Called by p2wi_HScrollActionProc, p2wi_VScrollActionProc
  1792. ******************************************************************************
  1793. */
  1794. static void p2wi_CommonScrollAction(ControlHandle control, short *amount)
  1795. {
  1796.     short        value, max;
  1797.     
  1798.     /* get the current value.. */
  1799.     value = GetControlValue(control);
  1800.  
  1801.     /* and the biggest value */
  1802.     max = GetControlMaximum(control);
  1803.  
  1804.     *amount = value - *amount;
  1805.     if ( *amount < 0 )
  1806.         *amount = 0;
  1807.     else if ( *amount > max )
  1808.         *amount = max;
  1809.     SetControlValue(control, *amount);
  1810.  
  1811.     /* figure out the delta change */
  1812.     *amount = value - *amount;
  1813. } // p2wi_CommonScrollAction
  1814.  
  1815.  
  1816. /*
  1817. ******************************************************************************
  1818. Name:
  1819.     p2wi_VScrollActionProc
  1820. ------------------------------------------------------------------------------
  1821. Purpose:
  1822.     Determines how much to change the value of the vertical scrollbar by,
  1823.     and how much to scroll the TE record.
  1824. ------------------------------------------------------------------------------
  1825. Description:
  1826.     
  1827. ------------------------------------------------------------------------------
  1828. Parameters:
  1829.     
  1830. ------------------------------------------------------------------------------
  1831. When Used:
  1832.     Callback routine, called by toolbox
  1833. ******************************************************************************
  1834. */
  1835. pascal void p2wi_VScrollActionProc(ControlHandle control, short part)
  1836. {
  1837.     short            amount;
  1838.     p2w_WindowPtr_t    p2w_Window;
  1839.     TEPtr            te;
  1840.     
  1841.     if (part != 0)
  1842.     {    /* if it was actually in the control */
  1843.         p2w_Window = (p2w_WindowPtr_t)(*control)->contrlOwner;
  1844.         te = *p2w_Window->p2wTEHandle;
  1845.         switch (part)
  1846.         {
  1847.             case kControlUpButtonPart:
  1848.             case kControlDownButtonPart:        /* one line */
  1849.                 amount = 1;
  1850.                 break;
  1851.             case kControlPageUpPart:            /* one page */
  1852.             case kControlPageDownPart:
  1853.                 amount = (te->viewRect.bottom - te->viewRect.top) / te->lineHeight;
  1854.                 break;
  1855.         }
  1856.         if ((part == kControlDownButtonPart) || (part == kControlPageDownPart))
  1857.             amount = -amount;        /* reverse direction if going down */
  1858.         p2wi_CommonScrollAction(control, &amount);
  1859.         if (amount != 0)
  1860.             TEScroll(0, amount * te->lineHeight, p2w_Window->p2wTEHandle);
  1861.     }
  1862. } // p2wi_VScrollActionProc
  1863.  
  1864.  
  1865. /*
  1866. ******************************************************************************
  1867. Name:
  1868.     p2wi_HScrollActionProc
  1869. ------------------------------------------------------------------------------
  1870. Purpose:
  1871.     Determines how much to change the value of the horizontal scrollbar by,
  1872.     and how much to scroll the TE record.
  1873. ------------------------------------------------------------------------------
  1874. Description:
  1875.     
  1876. ------------------------------------------------------------------------------
  1877. Parameters:
  1878.     
  1879. ------------------------------------------------------------------------------
  1880. When Used:
  1881.     Callback routine, called by toolbox
  1882. ******************************************************************************
  1883. */
  1884. pascal void p2wi_HScrollActionProc(ControlHandle control, short part)
  1885. {
  1886.     short            amount;
  1887.     p2w_WindowPtr_t    p2w_Window;
  1888.     TEPtr            te;
  1889.     
  1890.     if (part != 0)
  1891.     {    /* if it was actually in the control */
  1892.         p2w_Window = (p2w_WindowPtr_t)(*control)->contrlOwner;
  1893.         te = *p2w_Window->p2wTEHandle;
  1894.         switch (part)
  1895.         {
  1896.             case kControlUpButtonPart:
  1897.             case kControlDownButtonPart:        /* some pixels */
  1898.                 amount = kButtonScroll;
  1899.                 break;
  1900.             case kControlPageUpPart:            /* a whole page */
  1901.             case kControlPageDownPart:
  1902.                 amount = te->viewRect.right - te->viewRect.left;
  1903.                 break;
  1904.         }
  1905.         if ( (part == kControlDownButtonPart) || (part == kControlPageDownPart) )
  1906.             amount = -amount;        /* reverse direction.. */
  1907.         p2wi_CommonScrollAction(control, &amount);
  1908.         if ( amount != 0 )
  1909.             TEScroll(amount, 0, p2w_Window->p2wTEHandle);
  1910.     }
  1911. } // p2wi_HScrollActionProc
  1912.  
  1913.  
  1914. /*---------------------------------------------------------------------*/
  1915. /*==== Standard C library fns ====*/
  1916.  
  1917. /*
  1918. ******************************************************************************
  1919. Name:
  1920.     p2wi_StdCOut_BottleNeck
  1921. ------------------------------------------------------------------------------
  1922. Purpose:
  1923.     Internal Standard C output replacement common bottleneck routine..
  1924.     This is what they all call to actually display the string/character.
  1925. ------------------------------------------------------------------------------
  1926. Description:
  1927.     
  1928. ------------------------------------------------------------------------------
  1929. Parameters:
  1930.     
  1931. ------------------------------------------------------------------------------
  1932. When Used:
  1933.     
  1934. ******************************************************************************
  1935. */
  1936. static int p2wi_StdCOut_BottleNeck(FILE *stream)
  1937. {
  1938.     int        x;
  1939.     char    *OutBuf, *outp;
  1940.     short    OutSize;
  1941.  
  1942.     // get ahold of output buffer
  1943.     OutSize = **(short **)p2w_Stdio_OutBuf_Hdl;
  1944.     OutBuf = *p2w_Stdio_OutBuf_Hdl + sizeof(short);
  1945.     // make sure the string at least stops here! (maybe check strlen first for overflow errors?)
  1946.     *(OutBuf+kMaxStdIOBuffSize-1) = '\0';
  1947.  
  1948.     // If the output is for standard output (stderr/stdout) then capture it into our window,
  1949.     // else send it on to the standard C file output library routine.
  1950.     if ((stream == stderr) || (stream == stdout))
  1951.     {
  1952.         // Replace any line feeds (0x0a) with Macintosh carriage returns (0x0d)
  1953.         // This is mainly for Think C compatibility, since Think faithfully
  1954.         // literally adopted the K&R C idea (from Unix) that '\n' is really 0x0a,
  1955.         // and Apple's MPW C bends '\n' to 0x0d for better file compatibility.
  1956.  
  1957. /*
  1958. Note: For now, do this in both MPW and Think C.  This will FORCE the mapping
  1959. of any LFs to CRs.  The main reason for doing this is to catch the odd times
  1960. that the source code uses either '\r', or worse, '\0x0a' to embed returns!
  1961. */
  1962.         outp = OutBuf;
  1963.         for (x = 0; x < OutSize; x++)
  1964.         {
  1965.             if (*outp == 0x0a)
  1966.               *outp = 0x0d;
  1967.             if ((*outp != 0x0d) && (*outp < ' ')) // any other control chars, convert to space
  1968.                 *outp = ' ';
  1969.             outp++;
  1970.         }
  1971.  
  1972.         x = p2w_AddCString(local_p2wWindow, OutBuf, OutSize);    // add it into window
  1973.     }
  1974.     else
  1975.     {
  1976.         // call a real std. C library routine.  This allows output to real
  1977.         // stdio C files to pass through unmolested.
  1978.         x = fwrite(OutBuf, OutSize, 1, stream);
  1979.     }
  1980.  
  1981.     return x;
  1982.  
  1983. } // p2wi_StdCOut_BottleNeck
  1984.  
  1985.  
  1986. /*
  1987. ******************************************************************************
  1988. Name:
  1989.     p2wi_vfprintf
  1990. ------------------------------------------------------------------------------
  1991. Purpose:
  1992.     Internal common formatting handler for fprintf/printf
  1993. ------------------------------------------------------------------------------
  1994. Description:
  1995.     
  1996. ------------------------------------------------------------------------------
  1997. Parameters:
  1998.     
  1999. ------------------------------------------------------------------------------
  2000. When Used:
  2001.     
  2002. ******************************************************************************
  2003. */
  2004. static int p2wi_vfprintf(FILE *stream, const char *format, va_list va_args)
  2005. {
  2006.     int        x;
  2007.     char    *outBuf;
  2008.     short    *OutSizePtr;
  2009.  
  2010.     // get ahold of output buffer
  2011.     HLock(p2w_Stdio_OutBuf_Hdl);
  2012.     OutSizePtr = (short *)*p2w_Stdio_OutBuf_Hdl;
  2013.     outBuf = *p2w_Stdio_OutBuf_Hdl + sizeof(short);
  2014.  
  2015. #if defined(NEEDS_DEBUG)
  2016. {
  2017.     // stick in a TE-length value debug into the TE record
  2018.     int daLen = (**(local_p2wWindow->p2wTEHandle)).teLength;
  2019.     sprintf(outBuf, "[%5d] ",daLen);
  2020.     *OutSizePtr = 8;
  2021.     x = p2wi_StdCOut_BottleNeck(stream);
  2022. }
  2023. #endif // NEEDS_DEBUG
  2024.  
  2025.     // use C library routine to do printf formatting of the string into buffer
  2026.     x = vsprintf(outBuf, format, va_args); // format it into a string
  2027.     *OutSizePtr = strlen(outBuf);
  2028.  
  2029.     // do the window output
  2030.     x = p2wi_StdCOut_BottleNeck(stream);
  2031.  
  2032.     // cut buffer adrift again..
  2033.     HUnlock(p2w_Stdio_OutBuf_Hdl);
  2034.  
  2035.     return x;
  2036. } // p2wi_vfprintf
  2037.  
  2038.  
  2039.  
  2040. int p2w_fflush(FILE *stream)
  2041. {
  2042. #pragma unused (stream)
  2043.     int        x;
  2044.  
  2045.     /* major no-op, dude */
  2046.     x = 0;
  2047.     return x;
  2048. } // p2w_fflush
  2049.  
  2050.  
  2051.  
  2052.  
  2053. int p2w_fprintf(FILE *stream, const char *format, ...)
  2054. {
  2055.     va_list    va_args;
  2056.     int        x;
  2057.  
  2058.     // use our bottleneck routine to do printf formatting
  2059.     va_start(va_args, format);
  2060.     x = p2wi_vfprintf(stream, format, va_args); // format it into a string
  2061.     va_end(va_args);
  2062.  
  2063.     return x;
  2064. } // p2w_fprintf
  2065.  
  2066.  
  2067. int p2w_fputc(int theChar, FILE *stream)
  2068. {
  2069.     int        x;
  2070.     char    *outBuf;
  2071.     short    *OutSizePtr;
  2072.  
  2073.     // get ahold of output buffer & make char into string
  2074.     HLock(p2w_Stdio_OutBuf_Hdl);
  2075.     OutSizePtr = (short *)*p2w_Stdio_OutBuf_Hdl;
  2076.     outBuf = *p2w_Stdio_OutBuf_Hdl + sizeof(short);
  2077.  
  2078.     outBuf[0] = theChar;
  2079.     outBuf[1] = '\0';
  2080.     *OutSizePtr = 1;
  2081.  
  2082.     x = p2wi_StdCOut_BottleNeck(stream);
  2083.  
  2084.     HUnlock(p2w_Stdio_OutBuf_Hdl);
  2085.  
  2086.     return x;
  2087.  
  2088. } // p2w_fputc
  2089.  
  2090.  
  2091. int p2w_fputs(const char *theString, FILE *stream)
  2092. {
  2093.     int        x;
  2094.     char    *outBuf;
  2095.     short    *OutSizePtr;
  2096.  
  2097.     // get ahold of output buffer
  2098.     HLock(p2w_Stdio_OutBuf_Hdl);
  2099.     OutSizePtr = (short *)*p2w_Stdio_OutBuf_Hdl;
  2100.     outBuf = *p2w_Stdio_OutBuf_Hdl + sizeof(short);
  2101.  
  2102. //    *OutSizePtr = kMaxStdIOBuffSize;
  2103. //    ...changed to... [esp]
  2104.     *OutSizePtr = strlen(theString);
  2105.  
  2106.     // Copy string into buffer & write it
  2107. //    BlockMove(theString, outBuf, kMaxStdIOBuffSize);
  2108. //    ...changed to... [esp]
  2109.     BlockMove(theString, outBuf, 1+(*OutSizePtr));
  2110.  
  2111.     x = p2wi_StdCOut_BottleNeck(stream);
  2112.  
  2113.     // "puts()" puts a newline afterwards..
  2114.     if ((stream == stderr) || (stream == stdout))
  2115.         p2w_putc('\n', stream);
  2116.  
  2117.     // cut buffer adrift again..
  2118.     HUnlock(p2w_Stdio_OutBuf_Hdl);
  2119.  
  2120.     return x;
  2121. } // p2w_fputs
  2122.  
  2123.  
  2124. int p2w_printf(const char * format, ...)
  2125. {
  2126.     va_list    va_args;
  2127.     int        x;
  2128.  
  2129.     // use our bottleneck routine to do printf formatting
  2130.     va_start(va_args, format);
  2131.     x = p2wi_vfprintf(stdout, format, va_args); // format it into a string
  2132.     va_end(va_args);
  2133.  
  2134.     return x;
  2135. } // p2w_printf
  2136.  
  2137.  
  2138. int p2w_putc(int theChar, FILE *stream)
  2139. {
  2140.     return p2w_fputc(theChar, stream);
  2141. } // p2w_putc
  2142.  
  2143.  
  2144. int p2w_putchar(const char theChar)
  2145. {
  2146.     return p2w_fputc(theChar, stdout);
  2147. } // p2w_putchar
  2148.  
  2149.  
  2150. int p2w_puts(const char *theString)
  2151. {
  2152.     return p2w_fputs(theString, stdout);
  2153. } // p2w_puts
  2154.